/**
 * Reference: swfupload.js, swfupload.queue.js and libs/common/popup.js
 * 
 *                                           注释                   举例........................
 * ----------------------------------------------------------------------------------------------------
 * @param browse_id:                         上传按钮的ID            'spanButtonPlaceHolder'
 * @param upload_url                         上传php文件的路径       '.../upload.php'
 * @param callbackFunc                       上传以后执行的函数      'function() { ... }'
 * @param opts uniqueId                      显示不同的标识           1,2,3...
 *             debug                         是否打开提醒模式         1或0
 *             file_size_limit               上传文件大小上限         '100 MB'
 *             file_queue_limit              每次上传数量上限         1
 *             file_types                    上传文件类型             '*.jpg;*.jpeg;*.png;*.gif'
 *             file_type_description         上传文件类型描述         'Image Files'
 *             post_params                   传送到php端的参数        { id: 1 }
 *             button_image_url              上传按钮图片的路径       '.../upload.png'
 *             width                         上传按钮图片宽度         94
 *             height                        上传按钮图片高度         29
 *             is_file_uploading             是否是文件上传           1或0
 * @return
 */
function MyUpload(browse_id, upload_url, callbackFunc, opts) {
  var pos = MyUpload.findPos(document.getElementById(browse_id));
  var settings = {
    flash_url : "ext/plugin/common/swfupload_pioneer/assets/swfupload.swf",
    flash9_url : "ext/plugin/common/swfupload_pioneer/assets/swfupload_fp9.swf",
    upload_url : upload_url,
    post_params : (opts && opts.post_params) ? opts.post_params : null,
    file_size_limit : (opts && opts.file_size_limit) ? opts.file_size_limit : '100 MB',
    file_types : (opts && opts.file_types) ? opts.file_types : '*.jpg;*.jpeg;*.png;*.gif',
    file_types_description : (opts && opts.file_types_description) ? opts.file_types_description : 'Image Files',
    file_upload_limit : 0,
    file_queue_limit : (opts && opts.file_queue_limit) ? opts.file_queue_limit : 0,
    custom_settings : {
      progressTarget : 'fsUploadProgress' + ((opts && opts.uniqueId) ? opts.uniqueId : ''),
      statusTarget: 'divStatus' + ((opts && opts.uniqueId) ? opts.uniqueId : ''),
      cancelButtonId : 'btnCancel' + ((opts && opts.uniqueId) ? opts.uniqueId : ''),
      position : [ pos[0] + 150, pos[1] ],
      done : [],
      total : [],
      callbackFunc: callbackFunc,
      debug: (opts && opts.debug) ? opts.debug : 0,
      is_file_uploading: (opts && opts.is_file_uploading) ? opts.is_file_uploading : false,
      uniqueId:  (opts && opts.uniqueId) ? opts.uniqueId : 0
    },

    // Button settings
    button_image_url : (opts && opts.button_image_url) ? opts.button_image_url : 'ext/plugin/common/swfupload_pioneer/assets/browse2.png',
    button_width :(opts && opts.width) ? opts.width : 94,
    button_height : (opts && opts.height) ? opts.height : 29,
    button_placeholder_id : browse_id,
//    button_text: '<span class="theFont">Hello</span>',
//    button_text_style: '.theFont { font-size: 16; }',
    button_text_left_padding : 0,
    button_text_top_padding : 0,

    // The event handler functions are defined in handlers.js
    swfupload_preload_handler : preLoad,
    swfupload_load_failed_handler : loadFailed,
    file_queued_handler : fileQueued,
    file_queue_error_handler : fileQueueError,
    file_dialog_complete_handler : fileDialogComplete,
    upload_start_handler : uploadStart,
    upload_progress_handler : uploadProgress,
    upload_error_handler : uploadError,
    upload_success_handler : uploadSuccess,
    upload_complete_handler : uploadComplete,
    queue_complete_handler : queueComplete  // Queue plugin event
  };

  swfu = new SWFUpload(settings);
};

MyUpload.findPos = function(elem) {
  var curleft = 0, curtop = 0;
  if (elem.offsetParent) {
    curleft = elem.offsetLeft;
    curtop = elem.offsetTop;
    while ((elem = elem.offsetParent)) {
      curleft += elem.offsetLeft;
      curtop += elem.offsetTop;
    }
  }
  return [ curleft, curtop ];
};

function preLoad() {
  if (!this.support.loading) {
    alert("You need the Flash Player 9.028 or above to use SWFUpload.");
    return false;
  }
};

function loadFailed() {
  alert("Something went wrong while loading SWFUpload. If this were a real application we'd clean up and then give you an alternative");
};

function fileQueued(file) {
  try {
    this.customSettings.total[this.customSettings.total.length] = file;
  } catch (ex) {
    this.debug(ex);
  }
};


function fileQueueError(file, errorCode, message) {
  try {
    if (errorCode === SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED) {
      alert("You have attempted to queue too many files.\n" + (message === 0 ? "You have reached the upload limit." : "You may select " + (message > 1 ? "up to " + message + " files." : "one file.")));
      return;
    }
    switch (errorCode) {
    case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
      alert(file.name + ": File is too big.");
      this.debug("Error Code: File too big, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
      break;
    case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
      alert(file.name + ": Cannot upload Zero Byte files.");
      this.debug("Error Code: Zero byte file, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
      break;
    case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
      alert(file.name + ": invalid File Type.");
      this.debug("Error Code: Invalid File Type, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
      break;
    default:
      if (file !== null) {
        alert(file.name + ": Unhandled Error");
      }
      this.debug("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
      break;
    }
  } catch (ex) {
    this.debug(ex);
  }
};


function fileDialogComplete(numFilesSelected, numFilesQueued, numFilesInQueue) {
  try {
    if (numFilesSelected > 0) {
      document.getElementById(this.customSettings.cancelButtonId).className = 'cancel_enabled';
      document.getElementById(this.customSettings.cancelButtonId).disabled = false;
    }
    
    /* I want auto start the upload and I can do that here */
    this.startUpload();
  } catch (ex)  {
    this.debug(ex);
  }
};


function uploadStart(file) {
  try {
    var progress = new FileProgress(file, this.customSettings.progressTarget, this.customSettings.statusTarget, this.customSettings.uniqueId);
//    progress.setStatus("Uploading...");
    progress.toggleCancel(true, this);
    document.getElementById(this.customSettings.progressTarget).style.visibility = 'visible';
      
    var total = 0;
    for (var idx in this.customSettings.total) {
      var obj = this.customSettings.total[idx];
      total += parseFloat(obj.size, 10);
    }
    
    var done = 0;
    for (var idx in this.customSettings.done) {
      var obj = this.customSettings.done[idx];
      done += parseFloat(obj.size, 10);
    }
    
    if (this.customSettings.is_file_uploading) {
      var p_uploaded = roundNumber(done / 1024 / 1024, 1) + 'Mb';
      var t_uploaded = roundNumber(total / 1024 / 1024, 1) + 'Mb';
      progress.setStatus('<span style=\'color: #fff\'>0%</span>' + '<span style=\'color: #aaa; margin-left: 5px\'>( ' + p_uploaded + ' / ' + t_uploaded + '<span style=\'color: #aaa;margin-left: 10px\'>' + file.name + '&nbsp;Uploading... )' + '</span></span><span style=\'margin-left: 10px\';>You have uploaded:</span>');
    }  else {
      progress.setStatus('<span style=\'color: #fff\'>0%</span>' + '<span style=\'color: #aaa; margin-left: 5px\'>( ' + (this.customSettings.done.length) + ' / ' + (this.customSettings.total.length) + '&nbsp;Photos  <span style=\'color: #aaa;margin-left: 10px\'>' + file.name + '&nbsp;Uploading... )'  + '</span></span><span style=\'margin-left: 10px\';>You have uploaded:</span>');
    }
    
//    progress.setStatus('<span style=\'color: #fff\'>' + percent + '%</span>' + '<span style=\'color: #aaa; margin-left: 5px\'>( ' + uploaded + 'Mb / ' + total + 'Mb<span style=\'color: #aaa;margin-left: 10px\'>' + file.name + '&nbsp;Uploading... )'  + '</span></span>');
    
  }
  catch (ex) {}
  return true;
};

function uploadProgress(file, bytesLoaded, bytesTotal) {
  try {
    var total = 0;
    for (var idx in this.customSettings.total) {
      var obj = this.customSettings.total[idx];
      total += parseFloat(obj.size, 10);
    }
    
    var done = 0;
    for (var idx in this.customSettings.done) {
      var obj = this.customSettings.done[idx];
      done += parseFloat(obj.size, 10);
    }
    done += parseFloat(bytesLoaded, 10);

    var progress = new FileProgress(file, this.customSettings.progressTarget, this.customSettings.statusTarget, this.customSettings.uniqueId);
    
    if (this.customSettings.is_file_uploading) {
//    var percent = Math.ceil((bytesLoaded / bytesTotal) * 100);
      var percent = Math.ceil((done / total) * 100);
      progress.setProgress(percent);
      var p_uploaded = roundNumber(done / 1024 / 1024, 1) + 'Mb';
      var t_uploaded = roundNumber(total / 1024 / 1024, 1) + 'Mb';
      progress.setStatus('<span style=\'color: #fff\'>' + percent + '%</span>' + '<span style=\'color: #aaa; margin-left: 5px\'>( ' + p_uploaded + ' / ' + t_uploaded + '<span style=\'color: #aaa;margin-left: 10px\'>' + file.name + '&nbsp;Uploading... )'  + '</span></span><span style=\'margin-left: 10px\';>You have uploaded:</span>');
    } else {
      var percent = Math.ceil((done / total) * 100);
      progress.setProgress(percent);
      progress.setStatus('<span style=\'color: #fff\'>' + percent + '%</span>' + '<span style=\'color: #aaa; margin-left: 5px\'>( ' + (this.customSettings.done.length + 1) + ' / ' + (this.customSettings.total.length) + '&nbsp;Photos  <span style=\'color: #aaa;margin-left: 10px\'>' + file.name + '&nbsp;Uploading... )'  + '</span></span><span style=\'margin-left: 10px\';>You have uploaded:</span>');
    }
    
//    progress.setStatus('<span style=\'color: #fff\'>' + percent + '%</span>' + '<span style=\'color: #aaa; margin-left: 5px\'>( ' + uploaded + 'Mb / ' + total + 'Mb<span style=\'color: #aaa;margin-left: 10px\'>' + file.name + '&nbsp;Uploading... )'  + '</span></span>');
  } catch (ex) {
    this.debug(ex);
  }
};

function uploadError(file, errorCode, message) {
  try {
    var progress = new FileProgress(file, this.customSettings.progressTarget, this.customSettings.statusTarget, this.customSettings.uniqueId);
    progress.setError();
    progress.toggleCancel(false);

    switch (errorCode) {
    case SWFUpload.UPLOAD_ERROR.HTTP_ERROR:
      progress.setStatus("Upload Error: " + message);
      this.debug("Error Code: HTTP Error, File name: " + file.name + ", Message: " + message);
      break;
    case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED:
      progress.setStatus("Upload Failed.");
      this.debug("Error Code: Upload Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
      break;
    case SWFUpload.UPLOAD_ERROR.IO_ERROR:
      progress.setStatus("Server (IO) Error");
      this.debug("Error Code: IO Error, File name: " + file.name + ", Message: " + message);
      break;
    case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR:
      progress.setStatus("Security Error");
      this.debug("Error Code: Security Error, File name: " + file.name + ", Message: " + message);
      break;
    case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
      progress.setStatus("Upload limit exceeded.");
      this.debug("Error Code: Upload Limit Exceeded, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
      break;
    case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED:
      progress.setStatus("Failed Validation.  Upload skipped.");
      this.debug("Error Code: File Validation Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
      break;
    case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
      // If there aren't any files left (they were all cancelled) disable the cancel button
      if (this.getStats().files_queued === 0) {
        document.getElementById(this.customSettings.cancelButtonId).className = 'cancel_disabled';
        document.getElementById(this.customSettings.cancelButtonId).disabled = true;
      }
      progress.setStatus("Cancelled");
      progress.setCancelled();
      break;
    case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
      progress.setStatus("Stopped");
      break;
    default:
      progress.setStatus("Unhandled Error: " + errorCode);
      this.debug("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
      break;
    }
  } catch (ex) {
        this.debug(ex);
    }
};


function uploadSuccess(file, serverData) {
  if (this.customSettings.debug == 1) {
    alert(serverData);
  }
  try {
    this.customSettings.done[this.customSettings.done.length] = file;
    
    var total = 0;
    for (var idx in this.customSettings.total) {
      var obj = this.customSettings.total[idx];
      total += parseFloat(obj.size, 10);
    }
    
    var done = 0;
    for (var idx in this.customSettings.done) {
      var obj = this.customSettings.done[idx];
      done += parseFloat(obj.size, 10);
    }
    var percent = Math.ceil((done / total) * 100);

    var progress = new FileProgress(file, this.customSettings.progressTarget, this.customSettings.statusTarget, this.customSettings.uniqueId);
    
    progress.setComplete(percent);
    progress.toggleCancel(false);
    
  } catch (ex) {
    this.debug(ex);
  }
};

function uploadComplete(file) {
  if (this.getStats().files_queued === 0) {
    document.getElementById(this.customSettings.cancelButtonId).className = 'cancel_disabled';
    document.getElementById(this.customSettings.cancelButtonId).disabled = true;
  }
};


function queueComplete(file) {
  
  var total = 0;
  for (var idx in this.customSettings.total) {
    var obj = this.customSettings.total[idx];
    total += parseFloat(obj.size, 10);
  }
  
  var done = 0;
  for (var idx in this.customSettings.done) {
    var obj = this.customSettings.done[idx];
    done += parseFloat(obj.size, 10);
  }
  
  var progress = new FileProgress(file, this.customSettings.progressTarget, this.customSettings.statusTarget, this.customSettings.uniqueId);
  
  if (this.customSettings.is_file_uploading) {
    var p_uploaded = roundNumber(done / 1024 / 1024, 1) + 'Mb';
    var t_uploaded = roundNumber(total / 1024 / 1024, 1) + 'Mb';
    progress.setStatus('<span style=\'color: #fff\'>100%</span>' + '<span style=\'color: #aaa; margin-left: 5px\'>( ' + p_uploaded + ' / ' + t_uploaded + ' )' + '</span></span><span style=\'margin-left: 10px\';>You have uploaded:</span>');
  } else {
    progress.setStatus('<span style=\'color: #fff\'>100%</span>' + '<span style=\'color: #aaa; margin-left: 5px\'>( ' + (this.customSettings.done.length) + ' / ' + (this.customSettings.total.length) + '&nbsp;Photos )' + '</span></span><span style=\'margin-left: 10px\';>You have uploaded:</span>');
  }
  
  this.customSettings.done = [];
  this.customSettings.total = [];
  this.customSettings.callbackFunc();
  
//  location.reload();
};

/*
A simple class for displaying file information and progress
Note: This is a demonstration only and not part of SWFUpload.
Note: Some have had problems adapting this class in IE7. It may not be suitable for your application.
*/

//Constructor
//file is a SWFUpload file object
//targetID is the HTML element id attribute that the FileProgress HTML structure will be added to.
//Instantiating a new FileProgress object with an existing file will reuse/update the existing DOM elements
function FileProgress(file, targetID, statusID, uniqueId) {
  this.fileProgressID = 'divFileProgress' + uniqueId;
  this.fileStatusID = 'divFileStatus' + uniqueId;

  this.opacity = 100; 
  this.height = 0;

  this.fileProgressWrapper = document.getElementById(this.fileProgressID);
  this.fileStatusWarpper = document.getElementById(this.fileStatusID);


if (!this.fileProgressWrapper) {
  this.fileProgressWrapper = document.createElement("div");
  this.fileProgressWrapper.className = "progressWrapper";
  this.fileProgressWrapper.id = this.fileProgressID;
  
  this.fileProgressElement = document.createElement("div");
  this.fileProgressElement.className = "progressContainer";
  
  var progressCancel = document.createElement("a");
  progressCancel.className = "progressCancel";
  progressCancel.href = "#";
  progressCancel.style.visibility = "hidden";
  progressCancel.appendChild(document.createTextNode(" "));
  
  var progressBar = document.createElement("div");
  progressBar.className = "progressBarInProgress";
  
  this.fileProgressElement.appendChild(progressCancel);
  this.fileProgressElement.appendChild(progressBar);
  this.fileProgressWrapper.appendChild(this.fileProgressElement);
  
  document.getElementById(targetID).appendChild(this.fileProgressWrapper);
} else {
  this.fileProgressElement = this.fileProgressWrapper.firstChild;
}

if (!this.fileStatusWarpper) {
  
  this.fileStatusWarpper = document.createElement("div");
  this.fileStatusWarpper.className = "statusWrapper";
  this.fileStatusWarpper.id = this.fileStatusID;
  
  this.filestatusElement = document.createElement("div");
  this.filestatusElement.className = "statusContainer";
  
//  var progressText = document.createElement("div");
//  progressText.className = "progressName";
//  progressText.appendChild(document.createTextNode(file.name));

  var fileStatus = document.createElement("div");
  fileStatus.className = "progressBarStatus";
  fileStatus.innerHTML = "&nbsp;";

  
//  this.filestatusElement.appendChild(progressText);
  this.filestatusElement.appendChild(fileStatus);
  this.fileStatusWarpper.appendChild(this.filestatusElement);
  
  document.getElementById(statusID).appendChild(this.fileStatusWarpper);
  
} else {
//  this.fileProgressElement = this.fileProgressWrapper.firstChild;
//  this.reset();
  this.fileStatusElement = this.fileStatusWarpper.firstChild;
}

this.height = this.fileProgressWrapper.offsetHeight;
//this.setTimer(null);
}

FileProgress.prototype.setTimer = function (timer) {
this.fileProgressElement["FP_TIMER"] = timer;
};
FileProgress.prototype.getTimer = function (timer) {
return this.fileProgressElement["FP_TIMER"] || null;
};

FileProgress.prototype.reset = function () {
this.fileProgressElement.className = "progressContainer";
//this.fileStatusElement.className = "statusContainer";

//this.fileStatusElement.childNodes[0].innerHTML = "&nbsp;";
//this.fileStatusElement.childNodes[0].className = "progressBarStatus";

this.fileProgressElement.childNodes[1].className = "progressBarInProgress";
this.fileProgressElement.childNodes[1].style.width = "";

//this.appear();
};

FileProgress.prototype.setProgress = function (percentage) {
this.fileProgressElement.className = "progressContainer green";
this.fileProgressElement.childNodes[1].className = "progressBarInProgress";
this.fileProgressElement.childNodes[1].style.width = percentage + "%";
//this.appear();
};
FileProgress.prototype.setComplete = function (percentage) {
//this.fileProgressElement.className = "progressContainer blue";
//this.fileProgressElement.childNodes[1].className = "progressBarComplete";
this.fileProgressElement.childNodes[1].style.width = percentage + "%";

//var oSelf = this;
//this.setTimer(setTimeout(function () {
//  oSelf.disappear();
//}, 10000));
};
FileProgress.prototype.setError = function () {
this.fileProgressElement.className = "progressContainer red";
this.fileProgressElement.childNodes[1].className = "progressBarError";
this.fileProgressElement.childNodes[1].style.width = "";

//var oSelf = this;
//this.setTimer(setTimeout(function () {
//  oSelf.disappear();
//}, 5000));
};
FileProgress.prototype.setCancelled = function () {
this.fileProgressElement.className = "progressContainer";
this.fileProgressElement.childNodes[1].className = "progressBarError";
this.fileProgressElement.childNodes[1].style.width = "";

//var oSelf = this;
//this.setTimer(setTimeout(function () {
//  oSelf.disappear();
//}, 2000));
};
FileProgress.prototype.setStatus = function (status) {
this.fileStatusElement.className = "statusContainer";
this.fileStatusElement.childNodes[0].className = "progressBarStatus";
this.fileStatusElement.childNodes[0].innerHTML = status;
};

//Show/Hide the cancel button
FileProgress.prototype.toggleCancel = function (show, swfUploadInstance) {
this.fileProgressElement.childNodes[0].style.visibility = show ? "visible" : "hidden";
if (swfUploadInstance) {
  var fileID = this.fileProgressID;
  this.fileProgressElement.childNodes[0].onclick = function () {
    swfUploadInstance.cancelUpload(fileID);
    return false;
  };
}
};

FileProgress.prototype.appear = function () {
if (this.getTimer() !== null) {
  clearTimeout(this.getTimer());
  this.setTimer(null);
}

if (this.fileProgressWrapper.filters) {
  try {
    this.fileProgressWrapper.filters.item("DXImageTransform.Microsoft.Alpha").opacity = 100;
  } catch (e) {
    // If it is not set initially, the browser will throw an error.  This will set it if it is not set yet.
    this.fileProgressWrapper.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=100)";
  }
} else {
  this.fileProgressWrapper.style.opacity = 1;
}
  
this.fileProgressWrapper.style.height = "";

this.height = this.fileProgressWrapper.offsetHeight;
this.opacity = 100;
this.fileProgressWrapper.style.display = "";
};

//Fades out and clips away the FileProgress box.
FileProgress.prototype.disappear = function () {

var reduceOpacityBy = 15;
var reduceHeightBy = 4;
var rate = 30;  // 15 fps

if (this.opacity > 0) {
  this.opacity -= reduceOpacityBy;
  if (this.opacity < 0) {
    this.opacity = 0;
  }

  if (this.fileProgressWrapper.filters) {
    try {
      this.fileProgressWrapper.filters.item("DXImageTransform.Microsoft.Alpha").opacity = this.opacity;
    } catch (e) {
      // If it is not set initially, the browser will throw an error.  This will set it if it is not set yet.
      this.fileProgressWrapper.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + this.opacity + ")";
    }
  } else {
    this.fileProgressWrapper.style.opacity = this.opacity / 100;
  }
}

if (this.height > 0) {
  this.height -= reduceHeightBy;
  if (this.height < 0) {
    this.height = 0;
  }

  this.fileProgressWrapper.style.height = this.height + "px";
}

if (this.height > 0 || this.opacity > 0) {
  var oSelf = this;
  this.setTimer(setTimeout(function () {
    oSelf.disappear();
  }, rate));
} else {
  this.fileProgressWrapper.style.display = "none";
  this.setTimer(null);
}
};

function roundNumber(num, dec) {
  var result = Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
  return result;
}